#!/bin/sh

. /lib/dracut-lib.sh

PATH=$PATH:/sbin:/usr/sbin

[ -z "$1" ] && exit 1
[ -z "$2" ] && exit 1
[ -z "$3" ] && exit 1

# root is in the form root=9nbd:srv:imgpath[:fstype[:rootflags[:nbdopts]]]

# nbdopts:
# keyboot=path will copy keys from srv:path into kernel keyring
# auth=munge will bootstrap munge
# privport works with server export of noauth,privport

netif="$1"
root="$2"
NEWROOT="$3"

arg_n() {
    local pos=$3
    IFS=$2
    set $1
    IFS=' '
    shift $pos
    echo $1 
}
arg_split() {
    IFS=$2
    set $1
    IFS=' '
    echo $*
}

[ "`arg_n $root : 0`" = "9nbd" ] || return
nbdserver=`arg_n $root : 1`
nbdpath=`arg_n $root : 2`
nbdfstype=`arg_n $root : 3`
nbdflags=`arg_n $root : 4`
nbdopts=`arg_n $root : 5`

[ -n "$nbdfstype" ] || nbdfstype=auto

# look through the flags and see if any are overridden by the command line
# FIXME: rewrite!
nbdflags=${nbdflags},
while [ -n "$nbdflags" ]; do
    f=${nbdflags%%,*}
    nbdflags=${nbdflags#*,}
    if [ -z "$f" ]; then
        break
    fi
    if [ "$f" = "ro" -o "$f" = "rw" ]; then
        nbdrw=$f
        continue
    fi
    fsopts=${fsopts+$fsopts,}$f
done
getarg ro && nbdrw=ro
getarg rw && nbdrw=rw
fsopts=${fsopts+$fsopts,}${nbdrw}

# XXX better way to wait for the device to be made?
i=0
while [ ! -b /dev/nbd0 ]; do
    [ $i -ge 20 ] && exit 1
    if [ $UDEVVERSION -ge 143 ]; then
        udevadm settle --exit-if-exists=/dev/nbd0
    else
        sleep 0.1
    fi
    i=$(( $i + 1))
done

# Handle keyboot=path
# Load everything present in path (base64'ed) into the kernel keyring 
# Presumes path is exported with noauth,privport
keyboot() {
    local srv=$1
    local dir=$2
    local key

    for key in `diodls -p -s $srv -a $dir`; do
        diodcat -p -s $srv -a $dir $key | base64 | keyctl padd user $key @u
    done
}

# Handle auth=munge
# The purpose is to be able to use auth=munge with 9nbd
# Presumes keyboot with a key named munge.key
# This whole mess can be avoided by simply exporting root with noauth,privport
mungeboot() {
    local srv=$1
    local keyid=`keyctl search @u user munge.key`

    keyctl pipe $keyid | base64 -d >/tmp/munge.key
    chmod 600 /tmp/munge.key
    mkdir -p /var/run/munge /var/lib/munge /var/log/munge
    dioddate -S -s $srv # avoid rewound cred errors
    munged --key /tmp/munge.key
    echo "create user munge * |/usr/bin/munge" >/etc/request-key.conf
}

# Parse nbdopts and find any that require special handling
for arg in `arg_split $nbdopts ,`; do
    case $arg in 
        keyboot=*) # FIXME: delete arg from $nbdopts as it isn't one
            keyboot $nbdserver `arg_n $arg = 1`
            ;;
        auth=munge)
            mungeboot $nbdserver
            ;;
    esac     
done

echo mount.diod ${nbdopts:+-o$nbdopts} -a "$nbdserver:$nbdpath" /dev/nbd0
mount.diod ${nbdopts:+-o$nbdopts} -a "$nbdserver:$nbdpath" /dev/nbd0 || exit 1

# If we didn't get a root= on the command line, then we need to
# add the udev rules for mounting the nbd0 device
if [ ! -e /etc/udev/rules.d/99-mount.rules ]; then
    echo '[ -e /dev/root ] || { info=$(udevadm info --query=env --name=/dev/nbd0); [ -z "${info%%*ID_FS_TYPE*}" ] && { ln -s /dev/nbd0 /dev/root 2>/dev/null; :; };} && rm $job;' \
       > /initqueue-settled/9nbd.sh

    printf '/bin/mount -t %s -o %s %s %s\n' \
	   "$nbdfstype" "$fsopts" /dev/nbd0 "$NEWROOT" \
	> /mount/01-$$-9nbd.sh
fi

# NBD doesn't emit uevents when it gets connected, so kick it
echo change > /sys/block/nbd0/uevent
exit 0
